package com.perceptivesoftware.licensing.server.util;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.perceptivesoftware.licensing.client.common.util.ClientConstants;
import com.perceptivesoftware.licensing.client.dto.VideoDTO;
import com.videoprovider.api.VideoApi;
import com.videoprovider.model.Tag;
import com.videoprovider.model.Video;

public class TwistageUtil
{
	private static final Log logger = LogFactory.getLog(TwistageUtil.class);

	private static VideoApi api;

	private static void initializeVideoApi()
	{
		String licenseKey = "85ff51e865197";
		String companyId = "cloud-solutions";
		String baseUrl = ClientConstants.TWISTAGE_BASE_URL;

		api = VideoApi.forAccount(baseUrl, companyId, licenseKey);
	}

	/**
	 * This has been tested and works
	 * 
	 * @param video
	 */
	public static void deleteVideo(String video)
	{
		if (api == null)
		{
			initializeVideoApi();
		}

		try
		{
			api.deleteVideo(video);
		}
		catch (Exception e)
		{
			logger.error("Error attempting to delete video", e);
		}
	}

	public static List<VideoDTO> getAllVideos()
	{
		if (api == null)
		{
			initializeVideoApi();
		}

		String allVideosXml = api.getAllVideos(new HashMap(), "xml");

		List<VideoDTO> videos = getAllVideosFromXml(allVideosXml, 10, 0);

		System.out.println(">>>>>>>>>>>>>>>All Videos<<<<<<<<<<<<<<<");
		int count = 1;
		for (VideoDTO v : videos)
		{
			System.out.println("Video " + count + ": " + v.getTitle());
			count++;
		}

		return videos;
	}

	public static List<String> getAllVideoIds(String xml)
	{
		try
		{
			List<String> videoIds = new ArrayList<String>();
			final DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
			domFactory.setNamespaceAware(false);
			final DocumentBuilder builder = domFactory.newDocumentBuilder();
			final Document doc = builder.parse(new InputSource(new StringReader(xml)));

			final XPath xpath = XPathFactory.newInstance().newXPath();
			final XPathExpression expr = xpath.compile("//video-id/text()");
			final NodeList videoIdNodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

			for (int i = 0; i < videoIdNodes.getLength(); i++)
			{
				final String vidId = videoIdNodes.item(i).getNodeValue();
				videoIds.add(vidId);
			}

			return videoIds;
		}
		catch (XPathExpressionException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (SAXException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (ParserConfigurationException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new ArrayList<String>();
	}

	public static List<VideoDTO> getAllVideosFromXml(String xml, Integer limit, Integer offset)
	{
		List<String> videoIds = getAllVideoIds(xml);
		List<VideoDTO> allVideos = new ArrayList<VideoDTO>();

		for (String vidId : videoIds)
		{
			try
			{
				Video vid = api.getVideoMetadata(vidId);
				if (vid.isAvailable())
				{
					allVideos.add(getVideoDTO(vid));
				}
			}
			catch (Exception e)
			{
				//TODO 
			}
		}

		Collections.sort(allVideos, new Comparator<VideoDTO>() {

			@Override
			public int compare(final VideoDTO o1, final VideoDTO o2)
			{
				return o2.getCreatedAt().compareToIgnoreCase(o1.getCreatedAt());
			}
		});

		if (limit != null && allVideos.size() > limit)
		{
			List<VideoDTO> limitedVideos = new ArrayList<VideoDTO>();
			for (int x = offset; x < (limit + offset); x++)
			{
				limitedVideos.add(allVideos.get(x));
			}
			return allVideos;
		}

		return allVideos;
	}

	public static VideoDTO getVideoDTO(Video rawVideo)
	{
		VideoDTO dto = new VideoDTO();

		dto.setVideoId(rawVideo.getVideoId());
		dto.setTitle(rawVideo.getTitle());
		dto.setCreatedAt(rawVideo.getCreatedAtAsString());
		dto.setContributor(rawVideo.getContributor());
		dto.setDuration(rawVideo.getDuration());
		dto.setHitsCount(rawVideo.getHitsCount());
		dto.setDescription(rawVideo.getDescription());
		dto.setTotalSize(rawVideo.getTotalSize());

		String tags = "";

		for (Tag t : rawVideo.getTags())
		{
			if (tags.length() > 0)
			{
				tags += ",";
			}
			tags += t.getName();
		}
		dto.setTags(tags);

		return dto;
	}
}
